import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import re
import math

def pd_datetime2int(trading_day):
	str_trading_day = str(trading_day)
	reg = re.compile(r'\d{4}\-\d{2}\-\d{2}')
	return int(''.join(reg.findall(str_trading_day)[0].split('-')))

def handle_len0_exception(future, ST_trading_day, ST_timestamp):
	timestamp = ST_timestamp
	trading_day = pd.to_datetime(ST_trading_day, format = '%Y%m%d')
	trading_day = trading_day + pd.Timedelta(days = -1)
	future_clz = df.loc[(df['trading_day'] == pd_datetime2int(trading_day)) & (df['timestamp'] == timestamp), 'clz'].values.tolist()
	if len(future_clz) >= 1:
		return future_clz
	return -1
	
def sharpe_ratio(pnl_net):
	total_property = [x * 1000000 + 1000000 for x in pnl_net]
	daily_ex_profit_rate = []
	for i in range(1, len(total_property)):
		daily_ex_profit_rate.append((total_property[i] - total_property[i - 1]) / total_property[i - 1] - 0.027 / 252)
	daily_ex_profit_rate = np.asarray(daily_ex_profit_rate)
	return math.sqrt(252) * daily_ex_profit_rate.mean() / daily_ex_profit_rate.std()

def turnover(turnovers):
	turnovers_nparray = np.asarray([abs(x) for x in turnovers])
	return turnovers_nparray.mean() / 1000000

def avg_leverage(positions):
	positions_nparray = np.asarray([abs(x) for x in positions])
	return positions_nparray.mean() / 1000000

def matplotlib_drawing(future_market_days, pnl_net, turnovers, positions, ST_filename):
	x = pd.to_datetime(future_market_days, format = '%Y%m%d')
	plt.figure(figsize = (15, 6), dpi = 100)
	y = pnl_net
	plt.plot(x, pnl_net, label = 'pnl_net')
	# plt.plot(x, pnl, label = 'pnl')
	plt.xlabel = 'date'
	# plt.ylabel = 'pnl_net'
	plt.legend(loc = 'upper left')
	plt.grid(True)
	plt.title("sharpe ratio: {:.3f}, TurnOver: {:.3f}, AvgLeverage: {:.3f}".format(sharpe_ratio(pnl_net), turnover(turnovers), avg_leverage(positions)))
	plt.savefig(".\\" + ST_filename + ".png")
	plt.show()

# main
if __name__ == '__main__':

	print('>> Input 0 for "SampleTarget.csv", 1 for "SampleTarget1.csv", 2 for "SampleTarget2.csv", default "SampleTarget2.csv"')
	print('>> ', end = '')
	# ST_filename = 'SampleTarget'
	n = input()
	if n == '0':
		ST_filename = 'SampleTarget'
	elif n == '1':
		ST_filename = 'SampleTarget1'
	else:
		ST_filename = 'SampleTarget2'

	ST_filepath = ST_filename + '.csv'
	ST = pd.read_csv(ST_filepath)

	future_dfs = {}
	for future in ST.columns.tolist()[2:]:
		future_filepath = '.\\1m\\' + str(future) + '.ft'
		future_dfs[future] = pd.read_feather(future_filepath)

	print(future_dfs.keys())
	print(len(future_dfs.keys()))
	print(len(ST.columns.tolist()[2:]))

	currency_net = 1000000
	currency = 1000000
	ST_futures_amount = {}
	for future in ST.columns.tolist()[2:]:
		ST_futures_amount[future] = 0

	future_market_days = []
	pnl_net = []
	pnl = []
	turnovers = []
	positions = []
	total_fee = 0

	for index, ST_row in ST.iterrows():
		ST_trading_day = ST_row['trading_day']
		ST_timestamp = ST_row['timestamp']
		print(int(ST_trading_day))
		for future in ST.columns.tolist()[2:]:	# 平仓，计算现金与期货量
			if pd.notnull(ST_row[future]):
				df = future_dfs[future]
				future_clz = df.loc[(df['trading_day'] == ST_trading_day) & (df['timestamp'] == ST_timestamp), 'clz'].values.tolist()
				if len(future_clz) == 0:
					future_clz = handle_len0_exception(future, ST_trading_day, ST_timestamp)
					if future_clz == -1:
						continue
				if abs(ST_row[future]) <= 3:
					future_target = ST_row[future] * 1000000
				else:
					future_target = ST_row[future]

				surplus_amount = (ST_futures_amount[future] * future_clz[0] - future_target) * 0.9997 / future_clz[0]
				surplus_profit_net = (ST_futures_amount[future] * future_clz[0] - future_target) * 0.9997
				surplus_profit = ST_futures_amount[future] * future_clz[0] - future_target
				total_fee += (ST_futures_amount[future] * future_clz[0] - future_target) * 0.0003
				current_amount = ST_futures_amount[future] - surplus_amount
				
				currency_net += surplus_profit_net
				currency += surplus_profit
				ST_futures_amount[future] = current_amount
				turnovers.append(surplus_profit)
		
		iter_trading_day = ST_trading_day
		continue_flag = False
		while len(ST.loc[index+1:index+1, 'trading_day'].values.tolist()) != 0 and iter_trading_day != ST.loc[index+1:index+1, 'trading_day'].values.tolist()[0]:
			total_property_net = currency_net
			total_property = currency
			position = 0
				
			for future in ST.columns.tolist()[2:]:
				timestamp = 145900
				if ST_futures_amount[future] != 0:
					df = future_dfs[future]
					future_clz = df.loc[(df['trading_day'] == iter_trading_day) & (df['timestamp'] == timestamp), 'clz'].values.tolist()

					if len(future_clz) == 0:
						continue_flag = True
						break

					total_property_net += ST_futures_amount[future] * future_clz[0]
					total_property += ST_futures_amount[future] * future_clz[0]
					position += ST_futures_amount[future] * future_clz[0]
				

			iter_trading_day = pd.to_datetime(iter_trading_day, format = '%Y%m%d')
			iter_trading_day += pd.Timedelta(days = 1)
			iter_trading_day = pd_datetime2int(iter_trading_day)

			if continue_flag == True:
				continue_flag = False
				continue

			pnl_net.append(total_property_net - 1000000)
			pnl.append(total_property - 1000000)
			positions.append(position)
			future_market_days.append(iter_trading_day)
			
	# print(pnl_net)
	# print(pnl)
	# print(total_fee)
	# print(sharpe_ratio(pnl_net))

	pnl_net = [x / 1000000 for x in pnl_net]
	pnl = [x / 1000000 for x in pnl]

	matplotlib_drawing(future_market_days, pnl_net, turnovers, positions, ST_filename)
